import os
import time
from SocketProtocolTool import DataMgr


class Main():
    def __init__(self, xmlPath="./Data.xml", path="./CreateProto", pathLua="./CreateLuaProto", pathJava="./CreateJavaProto"):
        self.path = path
        self.pathLua = pathLua
        self.pathJava = pathJava
        self.LoadXml(xmlPath)

    def LoadXml(self, path="./Data.xml"):
        DataMgr.instance.LoadXml(path)

    def GetListByToBoolName(self, lst, boolName, isTrue):
        list = []
        for p in lst:
            if p.AttToBool == boolName:
                if p.AttToBoolResult == isTrue:
                    list.append(p)
        return list

    def ToLuaType(self, type, outType):
        str = ""
        str1=""
        if type == "short":
            str = "number"
            str1 = "0"
        elif type == "ushort":
            str = "number"
            str1 = "0"
        elif type == "int":
            str = "number"
            str1 = "0"
        elif type == "uint":
            str = "number"
            str1 = "0"
        elif type == "long":
            str = "number"
            str1 = "0"
        elif type == "ulong":
            str = "number"
            str1 = "0"
        elif type == "float":
            str = "number"
            str1 = "0"
        elif type == "string":
            str = "string"
            str1 = "\"\""
        elif type == "bool":
            str = "boolean"
            str1 = "false"
        elif type == "byte":
            str = "number"
            str1 = "0"

        if (outType == 0):
            return str, outType
        elif (outType == 1):
            return str1, outType
        else:
            return str, outType

    def ToJavaType(self, type, outType=0):
        str = ""
        str1=""
        if type == "short":
            str = "short"
            str1 = "0"
        elif type == "ushort":
            str = "short"
            str1 = "0"
        elif type == "int":
            str = "Integer"
            str1 = "0"
        elif type == "uint":
            str = "Integer"
            str1 = "0"
        elif type == "long":
            str = "Long"
            str1 = "0"
        elif type == "ulong":
            str = "Long"
            str1 = "0"
        elif type == "float":
            str = "Float"
            str1 = "0"
        elif type == "string":
            str = "String"
            str1 = "\"\""
        elif type == "bool":
            str = "Boolean"
            str1 = "false"
        elif type == "byte":
            str = "byte"
            str1 = "0"
        else:
            return type

        if (outType == 0):
            return str
        elif (outType == 1):
            return str1
        else:
            return str

    def ChangeTypeName(self, type):
        str = ""

        if type=="short":
            str = "Short()"
        elif type=="ushort":
            str = "UShort()"
        elif type=="int":
            str = "Int()"
        elif type=="uint":
            str = "UInt()"
        elif type=="long":
            str = "Long()"
        elif type=="ulong":
            str = "ULong()"
        elif type=="float":
            str = "Float()"
        elif type=="string":
            str = "UTF8String()"
        elif type==   "bool":
            str = "Bool()"
        elif type=="byte":
            str = "Byte()"
        return str

    def CreateProto(self, proto, isSave = False):
        # if (isSave):
        #     # 生成协议代码
        #     self.SaveProto()

        lst = DataMgr.instance.GetProtoArrtList(proto.ProtoID, proto.MenuID)

        sbr = ""
        sbrLua = ""
        sbrJava = ""

        # region c#协议代码开始
        sbr=sbr+("//===================================================\n")
        sbr=sbr+("//作    者：边涯  http://www.u3dol.com  QQ群：87481002\n")
        sbr=sbr+(f"//创建时间：{time.strftime('%Y-%m-%d %H:%M:%S')}\n")
        sbr=sbr+("//备    注：\n")
        sbr=sbr+("//===================================================\n")
        sbr=sbr+("using System.Collections;\n")
        sbr=sbr+("using System.Collections.Generic;\n")
        sbr=sbr+("using System;\n")
        sbr=sbr+("\n")
        sbr=sbr+("/// <summary>\n")
        sbr=sbr+(f"/// {proto.ProtoCnName}\n")
        sbr=sbr+("/// </summary>\n")
        sbr=sbr+(f"public struct {proto.ProtoEnName}Proto : IProto\n")
        sbr=sbr+("{\n")
        sbr=sbr+(f"    public ushort ProtoCode {{ get {{ return {proto.ProtoCode}; }} }}\n")
        sbr=sbr+("\n")
        #endregion

        #region lua协议代码开始

        sbrLua=sbrLua+(f"--{proto.ProtoCnName}\n")
        sbrLua=sbrLua+(f"{proto.ProtoEnName}Proto = {{ ProtoCode = {proto.ProtoCode}, ")

        for item in lst:
            if (item.AttToLoop != None):
                # 这里是循环项的从属属性

                sbrLua=sbrLua+(f"{item.AttEnName}Table = {{ }}, ")
            else:

                # 生成标准的基本属性
                if (item.AttToCus !=None):

                    sbrLua=sbrLua+(f"{item.AttEnName} = {self.ToLuaType(item.AttType, 1)}, ")

        sbrLua = sbrLua[:len(sbrLua)-2]
        sbrLua=sbrLua+(" }\n")
        sbrLua=sbrLua+("\n")

        sbrLua=sbrLua+("--这句是重定义元表的索引，就是说有了这句，这个才是一个类\n")
        sbrLua=sbrLua+(f"{proto.ProtoEnName}Proto.__index = {proto.ProtoEnName}Proto;\n")
        sbrLua=sbrLua+("\n")
        sbrLua=sbrLua+("function {proto.ProtoEnName}Proto.New()\n")
        sbrLua=sbrLua+("    local self = { }; --初始化self\n")
        sbrLua=sbrLua+("    setmetatable(self, {0}Proto); --将self的元表设定为Class\n".format(proto.ProtoEnName))
        sbrLua=sbrLua+("    return self;\n")
        sbrLua=sbrLua+("end\n")

        #endregion

        # region Java协议代码开始
        sbrJava = sbrJava + ("package com.mcx.modules.proto;\n")
        sbrJava = sbrJava + "\n"
        sbrJava = sbrJava + ("import com.mcx.modules.common.IProto;\n")
        sbrJava = sbrJava + (f"import com.mcx.modules.common.MMO_DataStream;\n")
        sbrJava = sbrJava + "\n"
        sbrJava = sbrJava + ("import java.io.*;\n")
        sbrJava = sbrJava + ("import java.util.*;\n")
        sbrJava = sbrJava + "\n"
        sbrJava = sbrJava + ("/**\n")
        sbrJava = sbrJava + (f" * {proto.ProtoCnName}\n")
        sbrJava = sbrJava + (" */\n")
        sbrJava = sbrJava + (f"public class {proto.ProtoEnName}Proto implements IProto\n")
        sbrJava = sbrJava + ("{\n")
        sbrJava += "    private static MMO_DataStream dataStream = new MMO_DataStream();\n\n"
        sbrJava += "    @Override\n"
        sbrJava = sbrJava + (f"    public short getProtoCode() {{ return {proto.ProtoCode}; }}\n")
        sbrJava = sbrJava + ("\n")
        # endregion

        for item in lst:
            if (not (item.AttToLoop == None or item.AttToLoop=="")):
                # 这里是循环项的从属属性
                sbr=sbr+("    public List<{0}> {1}List; //{2}\n".format(item.AttType, item.AttEnName, item.AttCnName))
                sbrJava = sbrJava + (
                    "    public ArrayList<{0}> {1}List; //{2}\n".format(self.ToJavaType(item.AttType), item.AttEnName, item.AttCnName))
            else:
                # 生成标准的基本属性
                if (item.AttToCus==None or item.AttToCus==""):
                    sbr=sbr+("    public {0} {1}; //{2}\n".format(item.AttType, item.AttEnName, item.AttCnName))
                    sbrJava = sbrJava + ("    public {0} {1}; //{2}\n".format(self.ToJavaType(item.AttType), item.AttEnName, item.AttCnName))

        sbr=sbr+("\n")
        sbrJava += "\n"

        #region 生成自定义类型结构
        for item in lst:
            # 如果是自定义属性类型
            if (item.AttType != "byte" and item.AttType != "short" and item.AttType != "int" and item.AttType != "long" and item.AttType != "string" and item.AttType != "char" and item.AttType != "float" and item.AttType != "decimal" and item.AttType != "bool" and item.AttType != "ushort"):

                sbr=sbr+("    /// <summary>\n")
                sbr=sbr+(f"    /// {item.AttCnName}\n")
                sbr=sbr+("    /// </summary>\n")
                sbr=sbr+(f"    public struct {item.AttType}\n")
                sbr=sbr+("    {\n")

                strForNextLua = ""

                sbrJava = sbrJava + ("    /**\n")
                sbrJava = sbrJava + (f"     * {item.AttCnName}\n")
                sbrJava = sbrJava + ("     */\n")
                sbrJava = sbrJava + (f"    public static class {item.AttType}\n")
                sbrJava = sbrJava + ("    {\n")

                #= == == == == == == == == == =隶属于此自定义项的属性 == == == == == == == == =
                # 查找隶属于这个循环项的

                list = []
                for p in lst:
                    if (item.AttEnName == p.AttToCus):
                        list.append(p)

                if (list != None and len(list) > 0):

                    for item2 in list:

                        # 把已经提前用的了设置一下
                        for p in lst:
                            if (item2.AttID == p.AttID):
                                p.AttIsUsed = True
                        sbr=sbr+("        public {0} {1}; //{2}\n".format(item2.AttType, item2.AttEnName, item2.AttCnName))

                        strForNextLua += (f"{item2.AttEnName} = {self.ToLuaType(item2.AttType, 1)}")

                        sbrJava=sbrJava+("        public {0} {1}; //{2}\n".format(self.ToJavaType(item2.AttType), item2.AttEnName, item2.AttCnName))


                sbr=sbr+("    }\n")
                sbr=sbr+("\n")

                sbrJava = sbrJava + ("    }\n")
                sbrJava = sbrJava + ("\n")

                #= == == == == == == == == == == =lua协议代码开始
                sbrLua=sbrLua+("\n")
                sbrLua=sbrLua+("\n")
                sbrLua=sbrLua+(f"--定义{item.AttCnName}\n")
                sbrLua=sbrLua+(f"{item.AttEnName} = {{ {strForNextLua.rstrip(',')} }}\n")
                sbrLua=sbrLua+(f"{item.AttEnName}.__index = {item.AttEnName};\n")
                sbrLua=sbrLua+(f"function {item.AttEnName}.New()\n")
                sbrLua=sbrLua+("    local self = { };\n")
                sbrLua=sbrLua+(f"    setmetatable(self, {item.AttEnName});\n")
                sbrLua=sbrLua+("    return self;\n")
                sbrLua=sbrLua+("end\n")
                #= == == == == == == == == == == =lua协议代码结束
        #endregion

        # region ToArray 方法
        sbr=sbr+("    public byte[] ToArray()\n")
        sbr=sbr+("    {\n")
        sbr=sbr+("        using (MMO_MemoryStream ms = new MMO_MemoryStream())\n")
        sbr=sbr+("        {\n")
        sbr=sbr+("            ms.WriteUShort(ProtoCode);\n")

        #= == == == == == == == == == == =lua协议代码开始
        sbrLua=sbrLua+("\n")
        sbrLua=sbrLua+("\n")
        sbrLua=sbrLua+("--发送协议\n")
        sbrLua=sbrLua+(f"function {proto.ProtoEnName}Proto.SendProto(proto)\n")
        sbrLua=sbrLua+("\n")
        sbrLua=sbrLua+("    local ms = CS.LuaHelper.Instance:CreateMemoryStream();\n")
        sbrLua=sbrLua+("    ms:WriteUShort(proto.ProtoCode);\n")
        sbrLua=sbrLua+("\n")
        #= == == == == == == == == == == =lua协议代码结束

        sbrJava = sbrJava + ("    public byte[] ToArray() {\n")
        sbrJava = sbrJava + ("        ByteArrayOutputStream out = new ByteArrayOutputStream();\n")
        sbrJava = sbrJava + ("        try (DataOutputStream outputStream = new DataOutputStream(out)) {\n")
        sbrJava = sbrJava + ("            dataStream.outputStream = outputStream;\n")
        sbrJava = sbrJava + ("            dataStream.WriteShort(getProtoCode());\n")

        # 写入数据流
        for item in lst:
            if (item.AttIsUsed): continue

            sbr=sbr+("            ms.Write{0}({1});\n".format(self.ChangeTypeName(item.AttType).replace("()", ""), item.AttEnName))

            #regionlua协议代码开始
            sbrLua=sbrLua+("    ms:Write{0}(proto.{1});\n".format(self.ChangeTypeName(item.AttType).replace("()", ""),
                                item.AttEnName))
            #endregion

            sbrJava+=("            dataStream.Write{0}({1});\n".format(self.ChangeTypeName(item.AttType).replace("()", ""), item.AttEnName))


            if (item.AttType == "bool"):
                # 如果是布尔变量
                # region 布尔
                isHasSuccess = False
                #region 查找隶属于这个bool成功的
                list = self.GetListByToBoolName(lst, item.AttEnName, 'true')
                if (list != None and len(list) > 0):
                    isHasSuccess = True
                    sbr=sbr+(f"            if({item.AttEnName})\n")
                    sbrLua=sbrLua+(f"    if(proto.{item.AttEnName}) then\n")
                    sbrJava += (f"            if({item.AttEnName}) {{\n")

                    sbr=sbr+("            {\n")
                    for item3 in list:
                        # 把已经提前用的了设置一下
                        for p in lst:
                            if p.AttID == item3.AttID:
                                p.AttIsUsed = True

                        # 然后写到这个bool变量下
                        sbr=sbr+(f"                ms.Write{self.ChangeTypeName(item3.AttType).replace('()', '')}({item3.AttEnName});\n")
                        sbrLua=sbrLua+(f"        ms:Write{self.ChangeTypeName(item3.AttType).replace('()', '')}({item3.AttEnName});\n")
                        sbrJava+=(f"                dataStream.Write{self.ChangeTypeName(item3.AttType).replace('()', '')}({item3.AttEnName});\n")


                    sbr=sbr+("            }\n")
                    sbrJava = sbrJava + ("            }\n")
                # endregion

                #region 查找隶属于这个bool失败的

                list = self.GetListByToBoolName(lst, item.AttEnName, 'false')
                if (list != None and len(lst) > 0):

                    if (isHasSuccess):

                        sbr=sbr+("            else\n")

                        sbrLua=sbrLua+("        else\n")

                        sbrJava += ("            else {\n")

                    else:

                        # 如果没有成功项
                        sbr=sbr+(f"            if(!{item.AttEnName})\n")
                        sbrLua=sbrLua+(f"    if(not proto.{item.AttEnName}) then\n")
                        sbrJava = sbrJava + (f"            if (!{item.AttEnName}) {{\n")

                    sbr=sbr+("            {\n")
                    for item4 in list:

                        # 把已经提前用的了设置一下
                        for p in lst:
                            if p.AttID == item4.AttID:
                                p.AttIsUsed = True

                        # 然后写到这个bool变量下
                        sbr=sbr+(f"                ms.Write{self.ChangeTypeName(item4.AttType).replace('()', '')}({item4.AttEnName});\n")
                        sbrLua=sbrLua+(f"        ms:Write{self.ChangeTypeName(item4.AttType).replace('()', '')}({item4.AttEnName});\n")
                        sbrJava+=(f"                dataStream.Write{self.ChangeTypeName(item4.AttType).replace('()', '')}({item4.AttEnName});\n")

                    sbr=sbr+("            }\n")
                    sbrJava += ("            }\n")
                #endregion
                sbrLua=sbrLua+("    end\n")
                # endregion
            elif ((item.AttType == "byte" or item.AttType == "short" or item.AttType == "int" or item.AttType == "long") and item.AttIsLoop=="true"):
                # region 循环项目

                sbr=sbr+(f"            for (int i = 0; i < {item.AttEnName}; i++)\n")

                #= == == == == == == == == == == =lua协议代码开始
                sbrLua=sbrLua+(f"    for i = 1, proto.{item.AttEnName}, 1 do\n")
                #= == == == == == == == == == == =lua协议代码结束

                sbrJava += (f"            for (int i = 0; i < {item.AttEnName}; i++) {{\n")

                sbr=sbr+("            {\n")
                # 查找隶属于这个循环项的
                list = []
                for p in lst:
                    if(p.AttToLoop == item.AttEnName):
                        list.append(p)
                if (list != None and len(list) > 0):

                    for item5 in list:

                        # 把已经提前用的了设置一下
                        for p in lst:
                            if p.AttID == item5.AttID:
                                item5.AttIsUsed = True

                        # 如果是自定义属性类型
                        if (item5.AttType != "byte" and item5.AttType != "short" and item5.AttType != "int" and item5.AttType != "long" and item5.AttType != "string" and item5.AttType != "char" and item5.AttType != "float" and item5.AttType != "decimal" and item5.AttType != "bool" and item5.AttType != "ushort"):

                            list2 = []
                            for p in lst:
                                if p.AttToCus == item5.AttEnName:
                                    list2.append(p)
                            if (list2 != None and len(list2) > 0):
                                for item6 in list2:

                                    # 把已经提前用的了设置一下
                                    for p in lst:
                                        if p.AttID == item6.AttID:
                                            p.AttIsUsed = True
                                    sbr=sbr+(f"                ms.Write{self.ChangeTypeName(item6.AttType).replace('()', '')}({item5.AttEnName}List[i].{item6.AttEnName});\n")
                                    sbrLua=sbrLua+(f"        ms:Write{self.ChangeTypeName(item6.AttType).replace('()', '')}({item5.AttEnName}List[i].{item6.AttEnName});\n")
                                    sbrJava += f"                dataStream.Write{self.ChangeTypeName(item6.AttType).replace('()', '')}({item5.AttEnName}List.get(i).{item6.AttEnName});\n"

                        else:

                            # 然后写到这个bool变量下
                            sbr=sbr+(f"                ms.Write{self.ChangeTypeName(item5.AttType).replace('()', '')}({item5.AttEnName}List[i]);\n")
                            sbrLua=sbrLua+(f"        ms:Write{self.ChangeTypeName(item5.AttType).replace('()', '')}({item5.AttEnName}List[i]);\n")
                            sbrJava+=(f"                dataStream.Write{self.ChangeTypeName(item5.AttType).replace('()', '')}({item5.AttEnName}List.get(i));\n")

                sbr=sbr+("            }\n")
                sbrJava = sbrJava + ("            }\n")

                #= == == == == == == == == == == =lua协议代码开始
                sbrLua=sbrLua+("    end\n")
                #= == == == == == == == == == == =lua协议代码结束

                # endregion

        sbr=sbr+("            return ms.ToArray();\n")
        sbr=sbr+("        }\n")
        sbr=sbr+("    }\n")
        sbr=sbr+("\n")

        #= == == == == == == == == == == =lua协议代码开始
        sbrLua=sbrLua+("\n")
        sbrLua=sbrLua+("    CS.LuaHelper.Instance:SendProto(ms:ToArray());\n")
        sbrLua=sbrLua+("    ms:Dispose();\n")
        sbrLua=sbrLua+("end\n")
        #= == == == == == == == == == == =lua协议代码结束

        sbrJava = sbrJava + ("        } catch (IOException e) {\n")
        sbrJava = sbrJava + ("            e.printStackTrace();\n")
        sbrJava = sbrJava + ("        }\n")
        sbrJava += "        return out.toByteArray();"
        sbrJava += "    }"
        sbrJava = sbrJava + ("\n")

        # endregion

        # region GetProto 方法

        sbr=sbr+(f"    public static {proto.ProtoEnName}Proto GetProto(byte[] buffer)\n")
        sbr=sbr+("    {\n")
        sbr=sbr+(f"        {proto.ProtoEnName}Proto proto = new {proto.ProtoEnName}Proto();\n")
        sbr=sbr+("        using (MMO_MemoryStream ms = new MMO_MemoryStream(buffer))\n")
        sbr=sbr+("        {\n")

        #= == == == == == == == == == == =lua协议代码开始
        sbrLua=sbrLua+("\n")
        sbrLua=sbrLua+("\n")
        sbrLua=sbrLua+("--解析协议\n")
        sbrLua=sbrLua+(f"function {proto.ProtoEnName}Proto.GetProto(buffer)\n")
        sbrLua=sbrLua+("\n")
        sbrLua=sbrLua+(f"    local proto = {proto.ProtoEnName}Proto.New(); --实例化一个协议对象\n")
        sbrLua=sbrLua+("    local ms = CS.LuaHelper.Instance:CreateMemoryStream(buffer);\n")
        sbrLua=sbrLua+("\n")
        #= == == == == == == == == == == =lua协议代码结束

        sbrJava += (f"    public static {proto.ProtoEnName}Proto GetProto(byte[] buffer) {{\n")
        sbrJava += (f"        {proto.ProtoEnName}Proto proto = new {proto.ProtoEnName}Proto();\n")
        sbrJava += ("        try (DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(buffer))) {\n")
        sbrJava += ("            dataStream.inputStream = inputStream;\n")

        # 从数据流读取
        for item in lst:
            if (item.AttIsUsed): continue

            if (item.AttType == "byte"):

                sbr = sbr+("            proto.{0} = (byte)ms.Read{1};\n".format(item.AttEnName,
                                     self.ChangeTypeName(item.AttType)))
                sbrLua = sbrLua + ("    proto.{0} = ms:Read{1};\n".format(item.AttEnName, self.ChangeTypeName(item.AttType)))
                sbrJava += ("            proto.{0} = (byte)dataStream.Read{1};\n".format(item.AttEnName,
                                                                              self.ChangeTypeName(item.AttType)))
            else:

                sbr = sbr+("            proto.{0} = ms.Read{1};\n".format(item.AttEnName,
                                     self.ChangeTypeName(item.AttType)))
                sbrLua = sbrLua + ("    proto.{0} = ms:Read{1};\n".format(item.AttEnName, self.ChangeTypeName(item.AttType)))
                sbrJava += ("            proto.{0} = dataStream.Read{1};\n".format(item.AttEnName,
                                                                            self.ChangeTypeName(item.AttType)))

            if (item.AttType == "bool"):
                # 如果是布尔变量
                # region 布尔
                isHasSuccess = False
                #region 查找隶属于这个bool成功的
                list = self.GetListByToBoolName(lst, item.AttEnName, 'true')
                if (list != None and len(list) > 0):
                    isHasSuccess = True
                    sbr=sbr+(f"            if(proto.{item.AttEnName})\n")
                    sbrLua=sbrLua+(f"    if(proto.{item.AttEnName}) then\n")
                    sbrJava += (f"            if(proto.{item.AttEnName}) {{\n")

                    sbr=sbr+("            {\n")
                    for item3 in list:
                        # 把已经提前用的了设置一下
                        for p in lst:
                            if p.AttID == item3.AttID:
                                p.AttIsUsed = True

                        # 然后写到这个bool变量下
                        if (item3.AttType == "byte"):

                            sbr=sbr+("                proto.{0} = (byte)ms.Read{1};\n".format(item3.AttEnName,
                                                self.ChangeTypeName(item3.AttType)))
                            sbrLua=sbrLua+("        proto.{0} = ms:Read{1};\n".format(item3.AttEnName,
                                                self.ChangeTypeName(item3.AttType)) )
                            sbrJava += ("                proto.{0} = (byte)dataStream.Read{1};\n".format(item3.AttEnName,
                                                                                                  self.ChangeTypeName(
                                                                                                      item3.AttType)))

                        else:

                            sbr=sbr+("                proto.{0} = ms.Read{1};\n".format(item3.AttEnName,
                                                self.ChangeTypeName(item3.AttType)))
                            sbrLua=sbrLua+("        proto.{0} = ms:Read{1};\n".format(item3.AttEnName,
                                                self.ChangeTypeName(item3.AttType)))
                            sbrJava += ("                proto.{0} = dataStream.Read{1};\n".format(item3.AttEnName,
                                                                                            self.ChangeTypeName(
                                                                                                item3.AttType)))

                    sbr=sbr+("            }\n")
                    sbrJava += ("            }\n")
                # endregion

                #region 查找隶属于这个bool失败的

                list = self.GetListByToBoolName(lst, item.AttEnName, 'false')
                if (list != None and len(lst) > 0):

                    if (isHasSuccess):

                        sbr=sbr+("            else\n")

                        sbrLua=sbrLua+("        else\n")

                        sbrJava += ("            else {\n")

                    else:

                        # 如果没有成功项
                        sbr=sbr+(f"            if(!proto.{item.AttEnName})\n")
                        sbrLua=sbrLua+(f"    if(not proto.{item.AttEnName}) then\n")
                        sbrJava += (f"            if(!proto.{item.AttEnName}) {{\n")

                    sbr=sbr+("            {\n")
                    for item4 in list:

                        # 把已经提前用的了设置一下
                        for p in lst:
                            if p.AttID == item4.AttID:
                                p.AttIsUsed = True

                        if (item4.AttType == "byte"):

                            # 然后写到这个bool变量下
                            sbr = sbr + ("                proto.{0} = (byte)ms.Read{1};\n".format(item4.AttEnName,
                                             self.ChangeTypeName(item4.AttType)))
                            sbrLua = sbrLua + ("        proto.{0} = ms:Read{1};\n".format(item4.AttEnName,
                                             self.ChangeTypeName(item4.AttType)))

                            sbrJava += ("                proto.{0} = (byte)dataStream.Read{1};\n".format(item4.AttEnName,
                                                                                                  self.ChangeTypeName(
                                                                                                      item4.AttType)))

                        else:

                            sbr = sbr + ("                proto.{0} = ms.Read{1};\n".format(item4.AttEnName,
                                             self.ChangeTypeName(item4.AttType)))
                            sbrLua = sbrLua + ("        proto.{0} = ms:Read{1};\n".format(item4.AttEnName,
                                             self.ChangeTypeName(item4.AttType)))
                            sbrJava += ("                proto.{0} = dataStream.Read{1};\n".format(item4.AttEnName,
                                                                                            self.ChangeTypeName(
                                                                                                item4.AttType)))

                    sbr=sbr+("            }\n")
                    sbrJava += ("            }\n")
                #endregion
                sbrLua=sbrLua+("    end\n")
                # endregion
            elif ((item.AttType == "byte" or item.AttType == "short" or item.AttType == "int" or item.AttType == "long") and item.AttIsLoop=="true"):
                # region 循环项目

                #= == == == == == == == == == == == == == == == == == == =
                # 1.定义列表

                list = []
                for p in lst:
                    if (p.AttToLoop == item.AttEnName):
                        list.append(p)
                if (list != None and len(list) > 0):

                    for item7 in list:
                        # 把已经提前用的了设置一下
                        for p in lst:
                            if (p.AttID == item7.AttID):
                                p.AttIsUsed = True
                                sbr = sbr + ("            proto.{0}List = new List<{1}>();\n".format(item7.AttEnName, item7.AttType))

                                sbrLua= sbrLua+("	proto.{0}Table = {{}};\n".format(item7.AttEnName))

                                sbrJava += ("            proto.{0}List = new ArrayList<{1}>();\n".format(item7.AttEnName, self.ToJavaType(item7.AttType)))

              #= == == == == == == == == == == == == == == == == == == =

                sbr=sbr+(f"            for (int i = 0; i < proto.{item.AttEnName}; i++)\n")

                #= == == == == == == == == == == =lua协议代码开始
                sbrLua=sbrLua+(f"    for i = 1, proto.{item.AttEnName}, 1 do\n")
                #= == == == == == == == == == == =lua协议代码结束

                sbrJava += (f"            for (int i = 0; i < proto.{item.AttEnName}; i++) {{\n")

                sbr=sbr+("            {\n")
                # 查找隶属于这个循环项的
                list = []
                for p in lst:
                    if(p.AttToLoop == item.AttEnName):
                        list.append(p)
                if (list != None and len(list) > 0):

                    for item5 in list:

                        # 把已经提前用的了设置一下
                        for p in lst:
                            if p.AttID == item5.AttID:
                                item5.AttIsUsed = True

                        # 如果是自定义属性类型
                        if (item5.AttType != "byte" and item5.AttType != "short" and item5.AttType != "int" and item5.AttType != "long" and item5.AttType != "string" and item5.AttType != "char" and item5.AttType != "float" and item5.AttType != "decimal" and item5.AttType != "bool" and item5.AttType != "ushort"):

                            list2 = []
                            for p in lst:
                                if p.AttToCus == item5.AttEnName:
                                    list2.append(p)
                            if (list2 != None and len(list2) > 0):
                                sbr = sbr + ("                {0} _{1} = new {0}();\n".format(item5.AttType,
                                                 item5.AttEnName))

                                sbrLua = sbrLua + ("        local _{1} = {0}.New();\n".format(item5.AttEnName,
                                                    item5.AttEnName))
                                sbrJava += ("                {0} _{1} = new {0}();\n".format(item5.AttType,
                                                                                              item5.AttEnName))
                                for item6 in list2:

                                    # 把已经提前用的了设置一下
                                    for p in lst:
                                        if p.AttID == item6.AttID:
                                            p.AttIsUsed = True
                                    if (item6.AttType == "byte"):

                                        sbr = sbr + ("                _{0}.{1} = (byte)ms.Read{2}();\n".format(item5.AttEnName, item6.AttEnName,
                                                             self.ChangeTypeName(item6.AttType).replace("()", "")))
                                        sbrLua = sbrLua + ("        _{0}.{1} = ms:Read{2}();\n".format(item5.AttEnName, item6.AttEnName,
                                                             self.ChangeTypeName(item6.AttType).replace("()", "")))
                                        sbrJava += (
                                            "                _{0}.{1} = (byte)dataStream.Read{2}();\n".format(item5.AttEnName,
                                                                                                      item6.AttEnName,
                                                                                                      self.ChangeTypeName(
                                                                                                          item6.AttType).replace(
                                                                                                          "()", "")))
                                    else:

                                        sbr = sbr + ("                _{0}.{1} = ms.Read{2}();\n".format(item5.AttEnName, item6.AttEnName,
                                                             self.ChangeTypeName(item6.AttType).replace("()", "")))
                                        sbrLua = sbrLua + ("        _{0}.{1} = ms:Read{2}();\n".format(item5.AttEnName, item6.AttEnName,
                                                             self.ChangeTypeName(item6.AttType).replace("()", "")))
                                        sbrJava += ("                _{0}.{1} = dataStream.Read{2}();\n".format(item5.AttEnName,
                                                                                                item6.AttEnName,
                                                                                                self.ChangeTypeName(
                                                                                                    item6.AttType).replace(
                                                                                                    "()", "")))

                                sbr = sbr + ("                proto.{0}List.Add(_{0});\n".format(item5.AttEnName))
                                sbrLua = sbrLua + ("        proto.{0}Table[#proto.{0}Table+1] = _{0};\n".format(item5.AttEnName))
                                sbrJava += ("                proto.{0}List.add(_{0});\n".format(item5.AttEnName))
                        else:
                            if (item5.AttType == "byte"):

                                # 然后写到这个bool变量下
                                sbr = sbr + ("                {0} _{1} = (byte)ms.Read{2}();  //{3}\n".format(item5.AttType, item5.AttEnName,
                                                 self.ChangeTypeName(item5.AttType).replace("()", ""), item5.AttCnName) )
                                sbrLua = sbrLua + ("        local _{1} = ms:Read{2}();  --{3}\n".format(item5.AttType, item5.AttEnName,
                                                 self.ChangeTypeName(item5.AttType).replace("()", ""), item5.AttCnName))
                                sbrJava += ("                {0} _{1} = (byte)dataStream.Read{2}();  //{3}\n".format(item5.AttType,
                                                                                                     item5.AttEnName,
                                                                                                     self.ChangeTypeName(
                                                                                                         item5.AttType).replace(
                                                                                                         "()", ""),
                                                                                                     item5.AttCnName))

                            else:

                                sbr = sbr + ("                {0} _{1} = ms.Read{2}();  //{3}\n".format(item5.AttType, item5.AttEnName,
                                                 self.ChangeTypeName(item5.AttType).replace("()", ""), item5.AttCnName))
                                sbrLua = sbrLua + ("        local _{1} = ms:Read{2}();  --{3}\n".format(item5.AttType, item5.AttEnName,
                                                 self.ChangeTypeName(item5.AttType).replace("()", ""), item5.AttCnName))
                                sbrJava += ("                {0} _{1} = dataStream.Read{2}();  //{3}\n".format(item5.AttType,
                                                                                                        item5.AttEnName,
                                                                                                        self.ChangeTypeName(
                                                                                                            item5.AttType).replace(
                                                                                                            "()", ""),
                                                                                                        item5.AttCnName))

                                sbr = sbr + ("                proto.{0}List.Add(_{0});\n".format(item5.AttEnName))
                                sbrLua = sbrLua + ("        proto.{0}Table[#proto.{0}Table+1] = _{0};\n".format(item5.AttEnName))
                                sbrJava += ("                proto.{0}List.add(_{0});\n".format(item5.AttEnName))

                sbr=sbr+("            }\n")

                #= == == == == == == == == == == =lua协议代码开始
                sbrLua=sbrLua+("    end\n")
                #= == == == == == == == == == == =lua协议代码结束

                sbrJava += ("            }\n")

                # endregion

        sbr=sbr+("        }\n")
        sbr=sbr+("        return proto;\n")
        sbr=sbr+("    }\n")

        sbrLua=sbrLua+("\n")
        sbrLua=sbrLua+("    ms:Dispose();\n")
        sbrLua=sbrLua+("    return proto;\n")
        sbrLua=sbrLua+("end")

        sbrJava += ("        } catch (IOException e) {\n")
        sbrJava += ("            e.printStackTrace();\n")
        sbrJava += ("        }\n")
        sbrJava += ("        return proto;\n")
        sbrJava += ("    }\n")

        #endregion

        sbr=sbr+("}")
        sbrJava += "}"

        if not os.path.isdir(self.path):
            os.makedirs(self.path)
        with open(f"{self.path}/{proto.ProtoEnName}Proto.cs", "w+", encoding='UTF-8') as fs:
            fs.write(sbr)

        if not os.path.isdir(self.pathLua):
            os.makedirs(self.pathLua)
        with open(f"{self.pathLua}/{proto.ProtoEnName}Proto.lua", "w+", encoding='UTF-8') as fs:
            fs.write(sbrLua)

        if not os.path.isdir(self.pathJava):
            os.makedirs(self.pathJava)
        with open(f"{self.pathJava}/{proto.ProtoEnName}Proto.java", "w+", encoding='UTF-8') as fs:
            fs.write(sbrJava)
        #endregion

    def CreateProtoCodeDef(self):
        sbr = ""

        sbr=sbr+("//===================================================\n")
        sbr=sbr+("//作    者：边涯  http://www.u3dol.com  QQ群：87481002\n")
        sbr=sbr+(f"//创建时间：{time.strftime('%Y-%m-%d %H:%M:%S')}\n")
        sbr=sbr+("//备    注：\n")
        sbr=sbr+("//===================================================\n")
        sbr=sbr+("using System.Collections;\n")
        sbr=sbr+("\n")
        sbr=sbr+("/// <summary>\n")
        sbr=sbr+("/// 协议编号定义\n")
        sbr=sbr+("/// </summary>\n")
        sbr=sbr+("public class ProtoCodeDef\n")
        sbr=sbr+("{\n")

        sbrLua = ""
        sbrLua=sbrLua+("ProtoCode=\n")
        sbrLua=sbrLua+("{\n")

        sbrJava = ""
        sbrJava = sbrJava + "package com.mcx.modules.proto;\n\n"
        sbrJava = sbrJava + "public class ProtoCodeDef\n"
        sbrJava = sbrJava + "{\n"


        for menu in DataMgr.instance.MenuList:
            for proto in menu.ProtoList:
                sbr=sbr+("    /// <summary>\n")
                sbr=sbr+(f"    /// {proto.ProtoCnName}\n")
                sbr=sbr+("    /// </summary>\n")
                sbr=sbr+(f"    public const ushort {proto.ProtoEnName} = {proto.ProtoCode};\n")
                sbr=sbr+("\n")

                sbrLua=sbrLua+(f"    {proto.ProtoEnName} = {proto.ProtoCode},\n")

                sbrJava = sbrJava + ("    /**\n")
                sbrJava = sbrJava + (f"    * {proto.ProtoCnName}\n")
                sbrJava = sbrJava + ("    */\n")
                sbrJava = sbrJava + (f"    public static short {proto.ProtoEnName} = {proto.ProtoCode};\n")
                sbrJava = sbrJava + ("\n")

        sbr=sbr+("}\n")

        sbrLua = sbrLua[: len(sbrLua)-2]
        sbrLua=sbrLua+("\n}")

        sbrJava = sbrJava + ("}\n")

        if not os.path.isdir(self.path):
            os.makedirs(self.path)
        with open(f"{self.path}/ProtoCodeDef.cs", "w+", encoding='UTF-8') as fs:
            fs.write(sbr)

        if not os.path.isdir(self.pathLua):
            os.makedirs(self.pathLua)
        with open(f"{self.pathLua}/ProtoCodeDef.lua", "w+", encoding='UTF-8') as fs:
            fs.write(sbrLua)

        if not os.path.isdir(self.pathJava):
            os.makedirs(self.pathJava)
        with open(f"{self.pathJava}/ProtoCodeDef.java", "w+", encoding='UTF-8') as fs:
            fs.write(sbrJava)


    def btnCreateAll_Click(self):
        self.CreateProtoCodeDef()

        for menu in DataMgr.instance.MenuList:
            for proto in menu.ProtoList:
                self.CreateProto(proto)

        print("代码生成完毕")
